home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-07 / sam303.zip / SAM.BAS < prev    next >
BASIC Source File  |  1991-03-01  |  46KB  |  1,236 lines

  1. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  2. '║  Main Module Name: SAM.BAS                                                                                                      ║
  3. '╟─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
  4. '║                                                                                                                                 ║
  5. '║       Purpose: S.A.M. (Server Activity Monitor) for LANtastic (tm) Networks.                                                    ║
  6. '║                                                                                                                                 ║
  7. '║        Source: Humbleware Custom Programming, Paul Martin Drive, Baltimore MD 21227, (H#) 301-799-1975  (W#) 301-685-7111       ║
  8. '║                                                                                                                                 ║
  9. '║        Author: Lawrence A. Westhaver                                                                                            ║
  10. '║                                                                                                                                 ║
  11. '║ Last Revision: March 1st 1991                                                                                                   ║
  12. '║                                                                                                                                 ║
  13. '║      Language: Microsoft BASIC Professional Development System (PDS)                                                            ║
  14. '║                                                                                                                                 ║
  15. '╟─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
  16. '║                                                                                                                                 ║
  17. '║ To run SAM interactively inside QBX environment: QBX SAM.BAS /L QBX.QLB                                                         ║
  18. '║                                                                                                                                 ║
  19. '╟─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
  20. '║                                                                                                                                 ║
  21. '║ To create a DOS command line executable SAM.EXE:                                                                                ║
  22. '║                                                                                                                                 ║
  23. '║         Libraries: QBX.QLB & QBX.LIB                                                                                            ║
  24. '║                                                                                                                                 ║
  25. '║        Stub Files: TSCNIONR.OBJ                                                                                                 ║
  26. '║                                                                                                                                 ║
  27. '║ Compiler Switches: /O /Ot /FPA                                                                                                  ║
  28. '║                                                                                                                                 ║
  29. '║   BC Command line: BC SAM.BAS, SAM.OBJ, NUL /O /Ot /FPA;                                                                        ║
  30. '║                                                                                                                                 ║
  31. '║                    Microsoft (R) BASIC Compiler Version 7.00                                                                    ║
  32. '║                    Copyright (C) Microsoft Corporation 1982-1989. All rights reserved.                                          ║
  33. '║                                                                                                                                 ║
  34. '║   Linker Switches: /EX /NOE                                                                                                     ║
  35. '║                                                                                                                                 ║
  36. '║ LINK Command line: LINK /EX /NOE SAM+TSCNIONR, SAM.EXE, NUL, QBX;                                                               ║
  37. '║                                                                                                                                 ║
  38. '║                    Microsoft (R) Segmented-Executable Linker  Version 5.05                                                      ║
  39. '║                    Copyright (C) Microsoft Corp 1984-1989.  All rights reserved.                                                ║
  40. '║                                                                                                                                 ║                                                                                  
  41. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  42. '
  43.  
  44.  
  45.         'define data structure used by InterruptX()
  46.         TYPE RegTypeX
  47.             AX    AS INTEGER
  48.             BX    AS INTEGER
  49.             CX    AS INTEGER
  50.             DX    AS INTEGER
  51.             BP    AS INTEGER
  52.             SI    AS INTEGER
  53.             DI    AS INTEGER
  54.             FLAGS AS INTEGER
  55.             DS    AS INTEGER
  56.             ES    AS INTEGER
  57.         END TYPE
  58.  
  59.  
  60.         'declare functions
  61.         DECLARE FUNCTION Parser$ (Delimiters$, InputString$)
  62.         DECLARE FUNCTION RedirIsThere% ()
  63.         DECLARE FUNCTION NOSVersion% ()
  64.         DECLARE FUNCTION LoggedInto% (Server$)
  65.         DECLARE FUNCTION TimeOut% (Seconds%, Default%)
  66.         DECLARE FUNCTION Rollover% ()
  67.  
  68.  
  69.         'declare sub-programs
  70.         DECLARE SUB InterruptX (IntNum AS INTEGER, InReg AS RegTypeX, OutReg AS RegTypeX)
  71.         DECLARE SUB DrawUpperScreen ()
  72.         DECLARE SUB DrawLowerScreen ()
  73.         DECLARE SUB UpdateScreen ()
  74.         DECLARE SUB ShowUsage ()
  75.  
  76.  
  77.         'define logical constants
  78.         CONST TRUE% = -1
  79.         CONST FALSE% = 0
  80.  
  81.  
  82.         'declare global variables
  83.         COMMON SHARED InReg AS RegTypeX, OutReg AS RegTypeX
  84.         COMMON SHARED BanrFG%, BanrBG%, InstFG%, InstBG%, BrdrFG%, BrdrBG%, TitlFG%, TitlBG%, TextFG%, TextBG%, ArowFG%, ArowBG%, StatFG%, StatBG%, NormFG%, NormBG%
  85.         COMMON SHARED PageStart%, State$(), LastCmd$(), Server$, Interval%, DisplayOption%
  86.  
  87.  
  88.         'move segment pointer into the BIOS data area
  89.         DEF SEG = 0
  90.  
  91.         'peek into BIOS data area to determine monitor type
  92.         IF PEEK(&H463) <> &HB4 THEN
  93.  
  94.             'If we have a color monitor, use the following colors a la' LANtastic (tm)
  95.  
  96.             BanrFG% = 15        'upper and lower program ID banners
  97.             BanrBG% = 1
  98.  
  99.             InstFG% = 14        'banner instructional hilites
  100.             InstBG% = 1
  101.  
  102.             BrdrFG% = 6         'window border
  103.             BrdrBG% = 7
  104.  
  105.             TitlFG% = 0         'titles within window border
  106.             TitlBG% = 7
  107.  
  108.             TextFG% = 15        'text within window border
  109.             TextBG% = 4
  110.                         
  111.             ArowFG% = 14        'scroll indicators (arrows)
  112.             ArowBG% = 7
  113.  
  114.             StatFG% = 15        'status panel hilites
  115.             StatBG% = 7
  116.  
  117.             NormFG% = 7         'normal DOS color
  118.             NormBG% = 0
  119.  
  120.         ELSE
  121.  
  122.             'If we have a monochrome monitor, use only bright whites, whites and blacks
  123.  
  124.             BanrFG% = 0         'upper and lower program ID banners
  125.             BanrBG% = 7
  126.  
  127.             InstFG% = 0         'banner instructional hilites
  128.             InstBG% = 7
  129.  
  130.             BrdrFG% = 7         'window border
  131.             BrdrBG% = 0
  132.  
  133.             TitlFG% = 7         'titles within window border
  134.             TitlBG% = 0
  135.  
  136.             TextFG% = 15        'text within window border
  137.             TextBG% = 0
  138.  
  139.             ArowFG% = 15        'scroll indicators (arrows)
  140.             ArowBG% = 0
  141.  
  142.             StatFG% = 15        'status panel hilites
  143.             StatBG% = 0
  144.  
  145.             NormFG% = 7         'normal DOS color
  146.             NormBG% = 0
  147.  
  148.         END IF
  149.  
  150.         'move segment pointer back to BASIC's data segment
  151.         DEF SEG
  152.  
  153.  
  154.         'position pointer to display users from top of list
  155.         PageStart% = 1
  156.  
  157.  
  158.         'allocate memory for login state flags
  159.         DIM State$(0 TO 255)
  160.  
  161.  
  162.         'generate all possible login state flag combinations and place them
  163.         'in a look-up table... the look-up table approach is much faster
  164.         'than generating the flags as needed during program execution
  165.         FOR Index% = 0 TO 255
  166.  
  167.             'create an un-initialized state flag string
  168.             State$(Index%) = STRING$(8, "-")
  169.  
  170.             'set Access Control List (ACL) privelege flag
  171.             IF Index% AND 128 THEN MID$(State$(Index%), 1) = "A"
  172.  
  173.             'set Queue privelege flag
  174.             IF Index% AND 64 THEN MID$(State$(Index%), 2) = "Q"
  175.  
  176.             'set Peer privelege flag
  177.             IF Index% AND 32 THEN MID$(State$(Index%), 3) = "P"
  178.  
  179.             'set Mail privelege flag
  180.             IF Index% AND 16 THEN MID$(State$(Index%), 4) = "M"
  181.  
  182.             'set User-audit-entry privelege flag
  183.             IF Index% AND 8 THEN MID$(State$(Index%), 5) = "U"
  184.  
  185.             'set Remote Program Load (RPL) flag
  186.             IF Index% AND 2 THEN MID$(State$(Index%), 7) = "R"
  187.  
  188.             'set fully Logged-In flag
  189.             IF Index% AND 1 THEN MID$(State$(Index%), 8) = "L"
  190.  
  191.         NEXT Index%
  192.  
  193.  
  194.         'allocate memory for NOS messages
  195.         DIM LastCmd$(0 TO 39)
  196.  
  197.  
  198.         'define NOS messages
  199.         LastCmd$(0) = "Log into a server       "
  200.         LastCmd$(1) = "Terminate process       "
  201.         LastCmd$(2) = "Open a file             "
  202.         LastCmd$(3) = "Close a file            "
  203.         LastCmd$(4) = "Create/Overwrite a file "
  204.         LastCmd$(5) = "Create a new file       "
  205.         LastCmd$(6) = "Create a unique file    "
  206.         LastCmd$(7) = "Commit data to disk     "
  207.         LastCmd$(8) = "Read from a file        "
  208.         LastCmd$(9) = "Write to a file         "
  209.         LastCmd$(10) = "Delete a file           "
  210.         LastCmd$(11) = "Set file attributes     "
  211.         LastCmd$(12) = "Lock byte range         "
  212.         LastCmd$(13) = "Unlock byte range       "
  213.         LastCmd$(14) = "Create a subdirectory   "
  214.         LastCmd$(15) = "Delete a subdirectory   "
  215.         LastCmd$(16) = "Rename a file           "
  216.         LastCmd$(17) = "Find first file match   "
  217.         LastCmd$(18) = "Find next file match    "
  218.         LastCmd$(19) = "Get disk free space     "
  219.         LastCmd$(20) = "Get a queue entry       "
  220.         LastCmd$(21) = "Set a queue entry       "
  221.         LastCmd$(22) = "Control the queue       "
  222.         LastCmd$(23) = "Get login information   "
  223.         LastCmd$(24) = "Get link description    "
  224.         LastCmd$(25) = "Seek to a file position "
  225.         LastCmd$(26) = "Get server's time       "
  226.         LastCmd$(27) = "Create an audit entry   "
  227.         LastCmd$(28) = "Open file in multi-mode "
  228.         LastCmd$(29) = "Change a password       "
  229.         LastCmd$(30) = "Disable user account    "
  230.         LastCmd$(31) = "Local server file copy  "
  231.         LastCmd$(32) = "Get username from acct  "
  232.         LastCmd$(33) = "Translate a path        "
  233.         LastCmd$(34) = "Create an indirect file "
  234.         LastCmd$(35) = "Get indirect file text  "
  235.         LastCmd$(36) = "Get phys printer status "
  236.         LastCmd$(37) = "Get logical stream info "
  237.         LastCmd$(38) = "Set logical stream info "
  238.         LastCmd$(39) = "Get user account record "
  239.  
  240.  
  241.         'check for minimum NOS configuration
  242.         IF NOT RedirIsThere% THEN
  243.             PRINT "Error: Artisoft network redirector (REDIR.EXE) not loaded"
  244.             END
  245.         END IF
  246.  
  247.  
  248.         'check for known compatible NOS version numbers
  249.         IF (NOSVersion% < 300) OR (NOSVersion% > 303) THEN
  250.             PRINT "Error: Artisoft network redirector (REDIR.EXE) version 3.00 to 3.03 required"
  251.             END
  252.         END IF
  253.  
  254.  
  255.         'fetch DOS command line
  256.         CmdLine$ = COMMAND$
  257.  
  258.  
  259.         'is command line empty?
  260.         IF CmdLine$ = "" THEN
  261.             CALL ShowUsage
  262.             PRINT "Error: You must specify the name of a server to monitor"
  263.             END
  264.         END IF
  265.  
  266.  
  267.         'fetch server name from command line
  268.         Server$ = Parser$(" ", CmdLine$)
  269.         IF NOT LoggedInto%(Server$) THEN
  270.             CALL ShowUsage
  271.             PRINT "Error: Can't find server, make sure you are logged into the specified server"
  272.             END
  273.         END IF
  274.  
  275.  
  276.         'fetch command line switches
  277.         DO
  278.  
  279.             'return next token
  280.             temp$ = Parser$(" " + CHR$(9), CmdLine$)
  281.  
  282.             'fetch display option from command line
  283.             IF LEFT$(temp$, 2) = "W=" THEN
  284.  
  285.                 IF (MID$(temp$, 3, 1) <> "P") AND (MID$(temp$, 3, 1) <> "S") THEN
  286.                     CALL ShowUsage
  287.                     PRINT "Error: Incorrect window option given, legal options are P or S"
  288.                     END
  289.                 END IF
  290.  
  291.                 IF MID$(temp$, 3, 1) = "P" THEN
  292.                     DisplayOption% = 0
  293.                 ELSE
  294.                     DisplayOption% = 1
  295.                 END IF
  296.  
  297.             END IF
  298.  
  299.             'fetch user number from command line
  300.             IF LEFT$(temp$, 2) = "U=" THEN
  301.  
  302.                 PageStart% = VAL(MID$(temp$, 3))
  303.  
  304.                 IF PageStart% < 1 OR PageStart% > 290 THEN
  305.                     CALL ShowUsage
  306.                     PRINT "Error: User number is out of range, legal range is 1 to 290"
  307.                     END
  308.                 END IF
  309.  
  310.             END IF
  311.  
  312.             'fetch update interval from command line
  313.             IF LEFT$(temp$, 2) = "I=" THEN
  314.  
  315.                 Interval% = VAL(MID$(temp$, 3))
  316.  
  317.                 IF Interval% < 0 OR Interval% > 300 THEN
  318.                     CALL ShowUsage
  319.                     PRINT "Error: Interval is out of range, legal range is 0 to 300 seconds"
  320.                     END
  321.                 END IF
  322.  
  323.             END IF
  324.  
  325.         LOOP UNTIL CmdLine$ = ""
  326.  
  327.  
  328.         'draw screen
  329.         CALL DrawUpperScreen
  330.         CALL DrawLowerScreen
  331.  
  332.  
  333.         'scan for users
  334.         CALL UpdateScreen
  335.  
  336.  
  337.         'main program loop
  338.         DO
  339.  
  340.             'force garbage collection
  341.             FreeStr& = FRE("")
  342.  
  343.             'fetch a keypress
  344.             KeyCode% = TimeOut%(Interval%, 32)
  345.  
  346.             SELECT CASE KeyCode%
  347.  
  348.                 CASE 13                         'carriage return
  349.  
  350.                     DisplayOption% = DisplayOption% + 1
  351.  
  352.                     IF DisplayOption% > 1 THEN
  353.                         DisplayOption% = 0
  354.                     END IF
  355.  
  356.                     CALL DrawUpperScreen
  357.  
  358.                     COLOR StatFG%, StatBG%
  359.  
  360.                     LOCATE 22, 23
  361.  
  362.                     SELECT CASE DisplayOption%
  363.  
  364.                         CASE 0
  365.  
  366.                             PRINT "Primary  ";
  367.  
  368.                         CASE 1
  369.  
  370.                             PRINT "Secondary";
  371.  
  372.                     END SELECT
  373.  
  374.                     'force an update
  375.                     KeyCode% = 32
  376.  
  377.  
  378.                 CASE 27                         'escape
  379.  
  380.                     COLOR NormFG%, NormBG%
  381.  
  382.                     CLS
  383.  
  384.                     LOCATE , , 1
  385.  
  386.                     PRINT "SAM - Server Activity Monitor Version 3.03 for LANtastic (tm) networks"
  387.                     PRINT
  388.                     PRINT "  (C) Copyright 1990 Humbleware Custom Programming"
  389.                     PRINT "  247 Paul Martin Drive"
  390.                     PRINT "  Baltimore, MD 21227"
  391.                     PRINT "  (301) 799-1975"
  392.                     PRINT
  393.  
  394.                     END
  395.  
  396.  
  397.                 CASE -72                        'up arrow
  398.  
  399.                     PageStart% = PageStart% - 1
  400.  
  401.                     IF PageStart% < 1 THEN
  402.                         PageStart% = 1
  403.                     END IF
  404.  
  405.                     COLOR StatFG%, StatBG%
  406.  
  407.                     LOCATE 20, 65
  408.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  409.  
  410.                     LOCATE 20, 72
  411.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  412.  
  413.                     'force an update
  414.                     KeyCode% = 32
  415.  
  416.  
  417.                 CASE -73                        'page up
  418.  
  419.                     PageStart% = PageStart% - 11
  420.  
  421.                     IF PageStart% < 1 THEN
  422.                         PageStart% = 1
  423.                     END IF
  424.  
  425.                     COLOR StatFG%, StatBG%
  426.  
  427.                     LOCATE 20, 65
  428.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  429.  
  430.                     LOCATE 20, 72
  431.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  432.  
  433.                     'force an update
  434.                     KeyCode% = 32
  435.  
  436.  
  437.                 CASE -71                        'home
  438.  
  439.                     PageStart% = 1
  440.  
  441.                     COLOR StatFG%, StatBG%
  442.  
  443.                     LOCATE 20, 65
  444.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  445.  
  446.                     LOCATE 20, 72
  447.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  448.  
  449.                     'force an update
  450.                     KeyCode% = 32
  451.  
  452.  
  453.                 CASE -80                        'down arrow
  454.  
  455.                     PageStart% = PageStart% + 1
  456.  
  457.                     IF PageStart% > 290 THEN
  458.                         PageStart% = 290
  459.                     END IF
  460.  
  461.                     COLOR StatFG%, StatBG%
  462.  
  463.                     LOCATE 20, 65
  464.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  465.  
  466.                     LOCATE 20, 72
  467.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  468.  
  469.                     'force an update
  470.                     KeyCode% = 32
  471.  
  472.  
  473.                 CASE -81                        'page down
  474.  
  475.                     PageStart% = PageStart% + 11
  476.  
  477.                     IF PageStart% > 290 THEN
  478.                         PageStart% = 290
  479.                     END IF
  480.  
  481.                     COLOR StatFG%, StatBG%
  482.  
  483.                     LOCATE 20, 65
  484.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  485.  
  486.                     LOCATE 20, 72
  487.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  488.  
  489.                     'force an update
  490.                     KeyCode% = 32
  491.  
  492.  
  493.                 CASE -79                        'end
  494.  
  495.                     PageStart% = 290
  496.  
  497.                     COLOR StatFG%, StatBG%
  498.  
  499.                     LOCATE 20, 65
  500.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  501.  
  502.                     LOCATE 20, 72
  503.                     PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  504.  
  505.                     'force an update
  506.                     KeyCode% = 32
  507.  
  508.  
  509.                 CASE 43                         'increment interval
  510.  
  511.                     Interval% = Interval% + 1
  512.  
  513.                     IF Interval% > 300 THEN
  514.                         Interval% = 0
  515.                     END IF
  516.  
  517.                     COLOR StatFG%, StatBG%
  518.  
  519.                     LOCATE 22, 65
  520.                     PRINT RIGHT$("000" + LTRIM$(STR$(Interval%)), 3);
  521.  
  522.  
  523.                 CASE 45                         'decrement interval
  524.  
  525.                     Interval% = Interval% - 1
  526.  
  527.                     IF Interval% < 0 THEN
  528.                         Interval% = 300
  529.                     END IF
  530.  
  531.                     COLOR StatFG%, StatBG%
  532.  
  533.                     LOCATE 22, 65
  534.                     PRINT RIGHT$("000" + LTRIM$(STR$(Interval%)), 3);
  535.  
  536.  
  537.             END SELECT
  538.  
  539.  
  540.             'if keypress is spacebar then update screen
  541.             IF KeyCode% = 32 THEN
  542.                 CALL UpdateScreen
  543.             END IF
  544.  
  545.         LOOP
  546.  
  547.  
  548. 'EOP: SAM 
  549.  
  550. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  551. '║ Sub-Program Name: DrawLowerScreen                                                                                               ║
  552. '║          Purpose: Draws lower half of S.A.M. (server activity monitor) screen.                                                  ║
  553. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  554. '
  555. SUB DrawLowerScreen
  556.  
  557.  
  558.         COLOR BanrFG%, BanrBG%
  559.  
  560.         LOCATE 1, 1:   PRINT "SAM - Server Activity Monitor   (C) Copyright 1990 Humbleware Custom Programming";
  561.  
  562.  
  563.         COLOR NormFG%, NormBG%
  564.  
  565.         LOCATE 2, 1:   PRINT SPACE$(80);
  566.         LOCATE 18, 1:  PRINT SPACE$(80);
  567.  
  568.  
  569.         COLOR BrdrFG%, BrdrBG%
  570.  
  571.         LOCATE 19, 1:  PRINT "╔══════════════════════════════════════════════════════════════════════════════╗";
  572.         LOCATE 20, 1:  PRINT "║                                                                              ║";
  573.         LOCATE 21, 1:  PRINT "╟──────────────────────────────────────────────────────────────────────────────╢";
  574.         LOCATE 22, 1:  PRINT "║                                                                              ║";
  575.         LOCATE 23, 1:  PRINT "╚══════════════════════════════════════════════════════════════════════════════╝";
  576.  
  577.  
  578.         COLOR TitlFG%, TitlBG%
  579.  
  580.         LOCATE 20, 2:  PRINT "  Monitoring Server:                         Monitoring Users:     to         ";
  581.         LOCATE 22, 2:  PRINT "     Display Window:                          Update Interval:     Second(s)  ";
  582.  
  583.  
  584.         COLOR NormFG%, NormBG%
  585.  
  586.         LOCATE 24, 1:  PRINT SPACE$(80);
  587.  
  588.  
  589.         COLOR BanrFG%, BanrBG%
  590.  
  591.         LOCATE 25, 1:  PRINT "     -Toggle Display,      -Quit,    /   -Scroll,    /   -Change Update Interval";
  592.  
  593.  
  594.         COLOR InstFG%, InstBG%
  595.  
  596.         LOCATE 25, 1:  PRINT "["; CHR$(17); CHR$(196); CHR$(217); "]";
  597.         LOCATE 25, 23: PRINT "[Esc]";
  598.         LOCATE 25, 35: PRINT "["; CHR$(24); "]";
  599.         LOCATE 25, 39: PRINT "["; CHR$(25); "]";
  600.         LOCATE 25, 51: PRINT "[+]";
  601.         LOCATE 25, 55: PRINT "[-]";
  602.  
  603.  
  604. END SUB 'DrawLowerScreen 
  605.  
  606. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  607. '║ Sub-Program Name: DrawUpperScreen                                                                                               ║
  608. '║          Purpose: Draws upper half of S.A.M. (server activity monitor) screen.                                                  ║
  609. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  610. '
  611. SUB DrawUpperScreen
  612.  
  613.  
  614.         'turn cursor off
  615.         LOCATE , , 0
  616.  
  617.  
  618.         'decide which display option we're using
  619.         SELECT CASE DisplayOption%
  620.  
  621.             'primary display window
  622.             CASE 0
  623.  
  624.                 COLOR BrdrFG%, BrdrBG%
  625.  
  626.                 LOCATE 3, 1:   PRINT "╔════╤═══════════════╤═══════════════╤════════╤══════════╤═════════════════╤═══╗";
  627.                 LOCATE 4, 1:   PRINT "║    │               │               │        │          │                 │   ║";
  628.  
  629.                 COLOR TitlFG%, TitlBG%
  630.  
  631.                 LOCATE 4, 2:   PRINT "VCID";
  632.                 LOCATE 4, 7:   PRINT " Machine Name  ";
  633.                 LOCATE 4, 23:  PRINT "   User Name   ";
  634.                 LOCATE 4, 39:  PRINT " State  ";
  635.                 LOCATE 4, 48:  PRINT " Requests ";
  636.                 LOCATE 4, 59:  PRINT "    I/O Bytes    ";
  637.                 LOCATE 4, 77:  PRINT "LCI";
  638.  
  639.                 COLOR BrdrFG%, BrdrBG%
  640.  
  641.                 LOCATE 5, 1:   PRINT "╠════╪═══════════════╪═══════════════╪════════╪══════════╪═════════════════╪═══╣";
  642.  
  643.                 FOR Index% = 6 TO 16
  644.  
  645.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 1:  PRINT CHR$(186);
  646.                     COLOR TextFG%, TextBG%: LOCATE Index%, 2:  PRINT SPACE$(4);
  647.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 6:  PRINT CHR$(179);
  648.                     COLOR TextFG%, TextBG%: LOCATE Index%, 7:  PRINT SPACE$(15);
  649.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 22: PRINT CHR$(179);
  650.                     COLOR TextFG%, TextBG%: LOCATE Index%, 23: PRINT SPACE$(15);
  651.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 38: PRINT CHR$(179);
  652.                     COLOR TextFG%, TextBG%: LOCATE Index%, 39: PRINT SPACE$(8);
  653.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 47: PRINT CHR$(179);
  654.                     COLOR TextFG%, TextBG%: LOCATE Index%, 48: PRINT SPACE$(10);
  655.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 58: PRINT CHR$(179);
  656.                     COLOR TextFG%, TextBG%: LOCATE Index%, 59: PRINT SPACE$(17);
  657.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 76: PRINT CHR$(179);
  658.                     COLOR TextFG%, TextBG%: LOCATE Index%, 77: PRINT SPACE$(3);
  659.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 80: PRINT CHR$(186);
  660.  
  661.                 NEXT Index%
  662.  
  663.                 COLOR BrdrFG%, BrdrBG%
  664.  
  665.                 LOCATE 17, 1:  PRINT "╚════╧═══════════════╧═══════════════╧════════╧══════════╧═════════════════╧═══╝";
  666.  
  667.             'secondary display window
  668.             CASE 1
  669.  
  670.                 COLOR BrdrFG%, BrdrBG%
  671.  
  672.                 LOCATE 3, 1:   PRINT "╔═══════════════╤════════╤══════════╤═════════════════╤════════════════════════╗";
  673.                 LOCATE 4, 1:   PRINT "║               │        │          │                 │                        ║";
  674.  
  675.                 COLOR TitlFG%, TitlBG%
  676.  
  677.                 LOCATE 4, 2:   PRINT "   User Name   ";
  678.                 LOCATE 4, 18:  PRINT " State  ";
  679.                 LOCATE 4, 27:  PRINT " Requests ";
  680.                 LOCATE 4, 38:  PRINT "    I/O Bytes    ";
  681.                 LOCATE 4, 56:  PRINT "  Last Command Issued   ";
  682.  
  683.                 COLOR BrdrFG%, BrdrBG%
  684.  
  685.                 LOCATE 5, 1:   PRINT "╠═══════════════╪════════╪══════════╪═════════════════╪════════════════════════╣";
  686.  
  687.                 FOR Index% = 6 TO 16
  688.  
  689.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 1:  PRINT CHR$(186);
  690.                     COLOR TextFG%, TextBG%: LOCATE Index%, 2:  PRINT SPACE$(15);
  691.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 17: PRINT CHR$(179);
  692.                     COLOR TextFG%, TextBG%: LOCATE Index%, 18: PRINT SPACE$(8);
  693.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 26: PRINT CHR$(179);
  694.                     COLOR TextFG%, TextBG%: LOCATE Index%, 27: PRINT SPACE$(10);
  695.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 37: PRINT CHR$(179);
  696.                     COLOR TextFG%, TextBG%: LOCATE Index%, 38: PRINT SPACE$(17);
  697.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 55: PRINT CHR$(179);
  698.                     COLOR TextFG%, TextBG%: LOCATE Index%, 56: PRINT SPACE$(24);
  699.                     COLOR BrdrFG%, BrdrBG%: LOCATE Index%, 80: PRINT CHR$(186);
  700.  
  701.                 NEXT Index%
  702.  
  703.                 COLOR BrdrFG%, BrdrBG%
  704.  
  705.                 LOCATE 17, 1:  PRINT "╚═══════════════╧════════╧══════════╧═════════════════╧════════════════════════╝";
  706.  
  707.         END SELECT
  708.  
  709.  
  710. END SUB 'DrawUpperScreen 
  711.  
  712. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  713. '║ Function Name: LoggedInto%                                                                                                      ║
  714. '║       Purpose: Returns a TRUE value if logged into specified server, FALSE otherwise.                                           ║
  715. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  716. '
  717. FUNCTION LoggedInto% (Server$)
  718.  
  719.  
  720.         'initialize index
  721.         Index% = 0
  722.  
  723.  
  724.         'main loop
  725.         DO
  726.  
  727.             'allocate buffer to receive server name
  728.             AvailableServer$ = STRING$(16, 0)
  729.  
  730.             'set up interrupt routine
  731.             InReg.ES = SSEG(AvailableServer$)       'load  ES with segment of AvailableServer$
  732.             InReg.DI = SADD(AvailableServer$)       'load  DI with offset of AvailableServer$
  733.             InReg.AX = &H5F80                       'load  AX with 5f80h
  734.             InReg.BX = Index%                       'load  BX with index
  735.  
  736.             'execute interrupt
  737.             CALL InterruptX(&H21, InReg, OutReg)
  738.  
  739.             'have we run out of servers?
  740.             IF (OutReg.FLAGS AND 1) THEN
  741.                 LoggedInto% = FALSE
  742.                 EXIT DO
  743.             END IF
  744.  
  745.             'do we have a server name match?
  746.             IF UCASE$(Server$) = "\\" + RTRIM$(LEFT$(AvailableServer$, 15)) THEN
  747.                 LoggedInto = TRUE
  748.                 EXIT DO
  749.             END IF
  750.  
  751.             'point to next server entry
  752.             Index% = Index% + 1
  753.  
  754.         LOOP
  755.  
  756.  
  757. END FUNCTION 'LoggedInto% 
  758.  
  759. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  760. '║ Function Name: FNNOSVer%                                                                                                        ║
  761. '║       Purpose: Returns Artisoft NOS version number in integer format. Version number 2.53 would be returned as 253.             ║
  762. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  763. '
  764. FUNCTION NOSVersion%
  765.  
  766.  
  767.         'set up interrupt routine
  768.         InReg.AX = &HB809
  769.  
  770.  
  771.         'execute interrupt
  772.         CALL InterruptX(&H2F, InReg, OutReg)
  773.  
  774.  
  775.         'interpret results
  776.         NOSVersion% = ((OutReg.AX \ 256) * 100) + (OutReg.AX AND 255)
  777.        
  778.  
  779. END FUNCTION 'NOSVersion% 
  780.  
  781. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  782. '║ Function Name: Parser$                                                                                                          ║
  783. '║       Purpose: Parses an input string into tokens.                                                                              ║
  784. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  785. '
  786. FUNCTION Parser$ (Delimiters$, InputString$)
  787.  
  788.  
  789.         'check for empty input string
  790.         IF InputString$ = "" THEN
  791.             Parser$ = ""
  792.             EXIT FUNCTION
  793.         END IF
  794.  
  795.  
  796.         'get length of input string for future reference
  797.         InputStringLength% = LEN(InputString$)
  798.  
  799.  
  800.         'throw away leading delimiters to find beginning of first token
  801.         FOR PointerToStartOfToken% = 1 TO InputStringLength%
  802.  
  803.             'jump out when we find a non-delimiter
  804.             IF INSTR(Delimiters$, MID$(InputString$, PointerToStartOfToken%, 1)) = 0 THEN
  805.                 EXIT FOR
  806.             END IF
  807.  
  808.         NEXT PointerToStartOfToken%
  809.  
  810.  
  811.         'resume scanning from where we left off to find end of first token
  812.         FOR PointerToEndOfToken% = PointerToStartOfToken% TO InputStringLength%
  813.  
  814.             'jump out when we find a delimiter
  815.             IF INSTR(Delimiters$, MID$(InputString$, PointerToEndOfToken%, 1)) <> 0 THEN
  816.                 EXIT FOR
  817.             END IF
  818.  
  819.         NEXT PointerToEndOfToken%
  820.  
  821.  
  822.         'see if we ran off the end of the input string looking for a non-delimiter
  823.         'if we did, then the input string contained no tokens
  824.         IF PointerToStartOfToken% > InputStringLength% THEN
  825.  
  826.             Parser$ = ""
  827.             InputString$ = ""
  828.             EXIT FUNCTION
  829.  
  830.         END IF
  831.  
  832.  
  833.         'see if we ran off the end of the input string looking for a delimiter
  834.         'if we did, then the rest of the input string is a single token
  835.         IF PointerToEndOfToken% > InputStringLength% THEN
  836.  
  837.             Parser$ = MID$(InputString$, PointerToStartOfToken%)
  838.             InputString$ = ""
  839.             EXIT FUNCTION
  840.  
  841.         END IF
  842.  
  843.  
  844.         'if we made it this far then we have pointers to the beginning and end
  845.         'of a token, let's send it back to the caller
  846.         Parser$ = MID$(InputString$, PointerToStartOfToken%, PointerToEndOfToken% - PointerToStartOfToken%)
  847.  
  848.  
  849.         'now we'll remove the token from the input string so it won't get processed again
  850.         InputString$ = MID$(InputString$, PointerToEndOfToken%)
  851.  
  852.  
  853. END FUNCTION 'Parser$ 
  854.  
  855. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  856. '║ Function Name: RedirIsThere%                                                                                                    ║
  857. '║       Purpose: Returns TRUE if Artisoft's REDIR.EXE is installed, FALSE otherwise.                                              ║
  858. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  859. '
  860. FUNCTION RedirIsThere%
  861.  
  862.  
  863.         'load  AX with b800h
  864.         InReg.AX = &HB800
  865.  
  866.  
  867.         'execute interrupt
  868.         CALL InterruptX(&H2F, InReg, OutReg)
  869.  
  870.  
  871.         'neither redir or server is installed
  872.         IF (OutReg.AX AND 255) = 0 THEN
  873.  
  874.             'set flag to false
  875.             RedirIsThere% = FALSE
  876.  
  877.         'something is installed
  878.         ELSE
  879.  
  880.             'is it redir?
  881.             IF ((OutReg.BX AND 255) AND 8) THEN
  882.  
  883.                 'set flag to true
  884.                 RedirIsThere% = TRUE
  885.  
  886.             ELSE
  887.  
  888.                 'set flag to false
  889.                 RedirIsThere% = FALSE
  890.  
  891.             END IF
  892.  
  893.         END IF
  894.  
  895.  
  896. END FUNCTION 'RedirIsThere% 
  897.  
  898. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  899. '║ Function Name: RollOver%                                                                                                        ║
  900. '║       Purpose: Fetches the BIOS midnight rollover flag from the BIOS data area.                                                 ║
  901. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  902. '
  903. FUNCTION Rollover%
  904.  
  905.  
  906.         'move BASIC's segment pointer to BIOS data area
  907.         DEF SEG = &H40
  908.  
  909.  
  910.         'get BIOS date rollover flag
  911.         Rollover% = PEEK(&H70)
  912.  
  913.  
  914.         'move BASIC's segment pointer back to BASIC's own data segment
  915.         DEF SEG
  916.  
  917.  
  918. END FUNCTION 'Rollover% 
  919.  
  920. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  921. '║ Subroutine Name: Usage                                                                                                          ║
  922. '║         Purpose: Prints usage instructions for SAM (server activity monitor).                                                   ║
  923. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  924. '
  925. SUB ShowUsage
  926.  
  927.  
  928.         PRINT
  929.         PRINT "Usage: SAM \\Servername [ [W={P|S}] [U=nnn] [I=nnn] ]"
  930.         PRINT
  931.         PRINT "  \\Servername  Name of network server to be monitored"
  932.         PRINT
  933.         PRINT "  Switch │ Meaning                             │ Default │ Options  "
  934.         PRINT "  W=     │ display primary or secondary Window │ P       │ P or S   "
  935.         PRINT "  U=     │ monitor Users starting at user nnn  │ 1       │ 1 to 290 "
  936.         PRINT "  I=     │ sets update Interval to nnn seconds │ 0       │ 0 to 300 "
  937.         PRINT
  938.         PRINT "  SAM \\Server W=S   - Monitors "; CHR$(34); "Server"; CHR$(34); ", display secondary window"
  939.         PRINT "  SAM \\Server U=2   - Monitors "; CHR$(34); "Server"; CHR$(34); ", monitor users starting at user 2"
  940.         PRINT "  SAM \\Server I=5   - Monitors "; CHR$(34); "Server"; CHR$(34); ", sets update interval to 5 seconds"
  941.         PRINT
  942.  
  943.  
  944. END SUB 'ShowUsage 
  945.  
  946. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  947. '║ Function Name: TimeOut%                                                                                                         ║
  948. '║       Purpose: Waits for keyboard input for a specified time period. Returns a default character if time elapses.               ║
  949. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  950. '
  951. FUNCTION TimeOut% (Seconds%, Default%) STATIC
  952.  
  953.  
  954.         'move BASIC's segment pointer to BIOS data area
  955.         DEF SEG = &H40
  956.  
  957.  
  958.         'convert seconds to clock ticks
  959.         TicksToWait% = Seconds% * 18
  960.  
  961.  
  962.         'reset counter
  963.         TickCount% = 0
  964.  
  965.  
  966.         'fetch current clock tick
  967.         ClockLowByte% = PEEK(&H6C)
  968.  
  969.  
  970.         'main loop
  971.         DO
  972.  
  973.  
  974.             'has at least one clock tick passed?
  975.             IF ClockLowByte% <> PEEK(&H6C) THEN
  976.  
  977.                 'update ClockLowByte
  978.                 ClockLowByte% = PEEK(&H6C)
  979.  
  980.                 'increment tick counter
  981.                 TickCount% = TickCount% + 1
  982.  
  983.             END IF
  984.  
  985.  
  986.             'check for a keypress
  987.             KeyCode$ = INKEY$
  988.  
  989.             'interpret keypress
  990.             SELECT CASE LEN(KeyCode$)
  991.  
  992.                 'got a regular keypress
  993.                 CASE 1
  994.  
  995.                     'return positive value for regular keys
  996.                     TimeOut% = ASC(KeyCode$)
  997.  
  998.                     EXIT DO
  999.  
  1000.                 'got an extended keypress
  1001.                 CASE 2
  1002.  
  1003.                     'return negative value for extended keys
  1004.                     TimeOut% = -ASC(RIGHT$(KeyCode$, 1))
  1005.  
  1006.                     EXIT DO
  1007.  
  1008.             END SELECT
  1009.  
  1010.  
  1011.             'is it time to exit?
  1012.             IF TickCount% >= TicksToWait% THEN
  1013.  
  1014.                 'return default character
  1015.                 TimeOut% = Default%
  1016.                 EXIT DO
  1017.  
  1018.             END IF
  1019.  
  1020.  
  1021.         'end main loop
  1022.         LOOP
  1023.  
  1024.  
  1025.         'move BASIC's segment pointer back to BASIC's own data segment
  1026.         DEF SEG = 0
  1027.  
  1028.  
  1029. END FUNCTION 'TimeOut% 
  1030.  
  1031. '╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
  1032. '║ Subroutine Name: UpdateScreen                                                                                                   ║
  1033. '║         Purpose: Updates S.A.M. (server activity monitor) screen.                                                               ║
  1034. '╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
  1035. '
  1036. SUB UpdateScreen STATIC
  1037.  
  1038.  
  1039.         'if BIOS midnight rollover flag has been set then force DOS to update
  1040.         'it's internal clock by making a dummy DOS get-time function call
  1041.         IF Rollover% THEN
  1042.             temp$ = TIME$
  1043.         END IF
  1044.  
  1045.  
  1046.         'condition server name
  1047.         ConditionedServer$ = Server$ + CHR$(0)
  1048.  
  1049.  
  1050.         'set color used by the following prints
  1051.         COLOR StatFG%, StatBG%
  1052.  
  1053.  
  1054.         'print display option
  1055.         LOCATE 22, 23
  1056.  
  1057.         SELECT CASE DisplayOption%
  1058.  
  1059.             CASE 0
  1060.  
  1061.                 PRINT "Primary  ";
  1062.  
  1063.             CASE 1
  1064.  
  1065.                 PRINT "Secondary";
  1066.  
  1067.         END SELECT
  1068.  
  1069.  
  1070.         'print server name
  1071.         LOCATE 20, 23
  1072.         PRINT MID$(Server$, 3);
  1073.  
  1074.  
  1075.         'print monitor range
  1076.         LOCATE 20, 65
  1077.         PRINT RIGHT$("000" + LTRIM$(STR$(PageStart%)), 3);
  1078.  
  1079.         LOCATE 20, 72
  1080.         PRINT RIGHT$("000" + LTRIM$(STR$(PageStart% + 10)), 3);
  1081.  
  1082.  
  1083.         'print update interval
  1084.         LOCATE 22, 65
  1085.         PRINT RIGHT$("000" + LTRIM$(STR$(Interval%)), 3);
  1086.  
  1087.  
  1088.         'set color used by the following prints
  1089.         COLOR TextFG%, TextBG%
  1090.  
  1091.  
  1092.         'point to first print line in display window
  1093.         Vert% = 6
  1094.  
  1095.  
  1096.         'reset login counter
  1097.         LoginCount% = 0
  1098.  
  1099.  
  1100.         'seed the login index
  1101.         OutReg.BX = 0
  1102.  
  1103.  
  1104.         'scan for logins
  1105.         DO
  1106.  
  1107.             'declare buffer to receive data
  1108.             UserEntry$ = SPACE$(44)
  1109.  
  1110.             'set up interrupt routine
  1111.             InReg.AX = &H5FB0                         'load AX with 5fb0h
  1112.             InReg.BX = OutReg.BX                      'load BX with scan index
  1113.             InReg.DS = SSEG(UserEntry$)               'load DS with segment of UserEntry$
  1114.             InReg.SI = SADD(UserEntry$)               'load SI with offset of UserEntry$
  1115.             InReg.ES = SSEG(ConditionedServer$)       'load ES with segment of ConditionedServer$
  1116.             InReg.DI = SADD(ConditionedServer$)       'load DI with offset of ConditionedServer$
  1117.  
  1118.             'execute interrupt
  1119.             CALL InterruptX(&H21, InReg, OutReg)
  1120.  
  1121.             
  1122.             IF (OutReg.FLAGS AND 1) THEN
  1123.  
  1124.                 'we have no more logins - bail out
  1125.                 EXIT DO
  1126.  
  1127.             ELSE
  1128.  
  1129.                 'we have another login - count it
  1130.                 LoginCount% = LoginCount% + 1
  1131.  
  1132.             END IF
  1133.  
  1134.  
  1135.             'is the login counter pointing to the 'window' we want to display?
  1136.             IF (LoginCount% >= PageStart%) AND (LoginCount% <= (PageStart% + 10)) THEN
  1137.  
  1138.                 'calculate virtual circuit number
  1139.                 VCID# = ASC(MID$(UserEntry$, 1, 1))
  1140.                 VCID# = VCID# + (ASC(MID$(UserEntry$, 2, 1)) * (2 ^ 8))
  1141.  
  1142.                 'calculate I/O bytes
  1143.                 InOut# = ASC(MID$(UserEntry$, 5, 1))
  1144.                 InOut# = InOut# + (ASC(MID$(UserEntry$, 6, 1)) * (2 ^ 8))
  1145.                 InOut# = InOut# + (ASC(MID$(UserEntry$, 7, 1)) * (2 ^ 16))
  1146.                 InOut# = InOut# + (ASC(MID$(UserEntry$, 8, 1)) * (2 ^ 24))
  1147.                 InOut# = InOut# + (ASC(MID$(UserEntry$, 9, 1)) * (2 ^ 32))
  1148.  
  1149.                 'calculate requests
  1150.                 Requests# = ASC(MID$(UserEntry$, 10, 1))
  1151.                 Requests# = Requests# + (ASC(MID$(UserEntry$, 11, 1)) * (2 ^ 8))
  1152.                 Requests# = Requests# + (ASC(MID$(UserEntry$, 12, 1)) * (2 ^ 16))
  1153.  
  1154.                 'print data to screen
  1155.                 SELECT CASE DisplayOption%
  1156.  
  1157.                     CASE 0
  1158.  
  1159.                         LOCATE Vert%, 2:  PRINT RIGHT$("000" + HEX$(VCID#), 4);
  1160.                         LOCATE Vert%, 7:  PRINT MID$(UserEntry$, 29, 15);
  1161.                         LOCATE Vert%, 23: PRINT MID$(UserEntry$, 13, 15);
  1162.                         LOCATE Vert%, 39: PRINT State$(ASC(MID$(UserEntry$, 3, 1)));
  1163.                         LOCATE Vert%, 48: PRINT USING "##,###,###"; Requests#;
  1164.                         LOCATE Vert%, 59: PRINT USING "#,###,###,###,###"; InOut#;
  1165.                         LOCATE Vert%, 77: PRINT USING "###"; ASC(MID$(UserEntry$, 4, 1));
  1166.  
  1167.                     CASE 1
  1168.  
  1169.                         LOCATE Vert%, 2:  PRINT MID$(UserEntry$, 13, 15);
  1170.                         LOCATE Vert%, 18: PRINT State$(ASC(MID$(UserEntry$, 3, 1)));
  1171.                         LOCATE Vert%, 27: PRINT USING "##,###,###"; Requests#;
  1172.                         LOCATE Vert%, 38: PRINT USING "#,###,###,###,###"; InOut#;
  1173.                         LOCATE Vert%, 56: PRINT LastCmd$(ASC(MID$(UserEntry$, 4, 1)));
  1174.  
  1175.                 END SELECT
  1176.  
  1177.                 'point to next print line in display window
  1178.                 Vert% = Vert% + 1
  1179.  
  1180.             END IF
  1181.  
  1182.         LOOP
  1183.  
  1184.  
  1185.         'if data did not fill all window lines then blank-out the rest
  1186.         FOR Index% = Vert% TO 16
  1187.  
  1188.             SELECT CASE DisplayOption%
  1189.  
  1190.                 CASE 0
  1191.  
  1192.                     LOCATE Index%, 2:  PRINT SPACE$(4);
  1193.                     LOCATE Index%, 7:  PRINT SPACE$(15);
  1194.                     LOCATE Index%, 23: PRINT SPACE$(15);
  1195.                     LOCATE Index%, 39: PRINT SPACE$(8);
  1196.                     LOCATE Index%, 48: PRINT SPACE$(10);
  1197.                     LOCATE Index%, 59: PRINT SPACE$(17);
  1198.                     LOCATE Index%, 77: PRINT SPACE$(3);
  1199.  
  1200.                 CASE 1
  1201.  
  1202.                     LOCATE Index%, 2:  PRINT SPACE$(15);
  1203.                     LOCATE Index%, 18: PRINT SPACE$(8);
  1204.                     LOCATE Index%, 27: PRINT SPACE$(10);
  1205.                     LOCATE Index%, 38: PRINT SPACE$(17);
  1206.                     LOCATE Index%, 56: PRINT SPACE$(24);
  1207.  
  1208.             END SELECT
  1209.  
  1210.         NEXT Index%
  1211.  
  1212.  
  1213.         'are there any entries above window?
  1214.         LOCATE 6, 80
  1215.         IF PageStart% > 1 THEN
  1216.             COLOR ArowFG%, ArowBG%
  1217.             PRINT CHR$(24);
  1218.         ELSE
  1219.             COLOR BrdrFG%, BrdrBG%
  1220.             PRINT CHR$(186);
  1221.         END IF
  1222.  
  1223.         'are there any entries below window?
  1224.         LOCATE 16, 80
  1225.         IF (PageStart% + 10) < LoginCount% THEN
  1226.             COLOR ArowFG%, ArowBG%
  1227.             PRINT CHR$(25);
  1228.         ELSE
  1229.             COLOR BrdrFG%, BrdrBG%
  1230.             PRINT CHR$(186);
  1231.         END IF
  1232.  
  1233.  
  1234. END SUB 'UpdateScreen 
  1235.  
  1236.